package com.dyh.quickdemo.demos.timingTask;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;

import java.util.concurrent.*;
import java.util.function.Function;

/*
@Author=Joey Wheeler
@Date=2020/10/21 14:24
有执行时间限制的Function
*/
@Setter@Getter@AllArgsConstructor
public class TimingFc<T,R> implements Function<T,R> {

    private long limitMilliseconds;
    private Function<T,R> core;
    private Function<T,R> fallBack;
    private ScheduledThreadPoolExecutor killerExecutor;//强引用

    @SneakyThrows
    @Override
    public R apply(T t) {
        CompletableFuture<R> coreFuture = CompletableFuture.supplyAsync(
                () -> core.apply(t)
        );
        CompletableFuture<R> fallBackFuture = CompletableFuture.supplyAsync(
                () -> {
                    try {
                        return killerExecutor.schedule(() -> fallBack.apply(t), limitMilliseconds, TimeUnit.MILLISECONDS).get();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (ExecutionException e) {
                        e.printStackTrace();
                    }
                    return null;
                }
        );
        /*谁快返回谁的结果*/
        CompletableFuture<R> combineFuture = coreFuture.applyToEither(fallBackFuture,Function.identity());
        return combineFuture.get();
    }


    public static void main(String[] args) {
        Function<String,Integer> fun = s->{
            try {
                Thread.sleep(s.length()*1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return s.length();
        };

        ScheduledThreadPoolExecutor threadPoolExecutor =new ScheduledThreadPoolExecutor(1);
        TimingFc<String,Integer> timingFc = new TimingFc(2000,fun,s->-1,threadPoolExecutor);

        Object res1 = timingFc.apply("12");
        System.out.println(res1);

        Object res2 = timingFc.apply("123");
        System.out.println(res2);
    }
}

/*
@Setter@Getter@AllArgsConstructor
public class TimingFc<T,R> implements Function<T,R> {

    private long limitMilliseconds;
    private Function<T,R> core;
    private Function<T,R> fallBack;
    private ScheduledThreadPoolExecutor killerExecutor;//强引用
    private ScheduledExecutorService coreExecutor;

    @SneakyThrows
    @Override
    public R apply(T t) {
        ScheduledFuture<R> killFucture = killerExecutor.schedule(()->fallBack.apply(t),limitMilliseconds, TimeUnit.MILLISECONDS);

        Future<R> coreFuture = coreExecutor.submit(()->{
            R r = null;
            r = core.apply(t);
            killFucture.cancel(true);
            return r;
        });

        return coreFuture.get();
    }
}
*/
